package yiran.agift.manager;

import yiran.agift.AGift;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseManager {
    private Connection connection;
    private final String connectionString;
    private final String username;
    private final String password;
    public DatabaseManager() {
        String dbType = AGift.getInstance().getConfig().getString("database.type", "sqlite");

        if ("mysql".equalsIgnoreCase(dbType)) {
            String host = AGift.getInstance().getConfig().getString("database.mysql.host");
            int port = AGift.getInstance().getConfig().getInt("database.mysql.port");
            String dbName = AGift.getInstance().getConfig().getString("database.mysql.database");
            this.username = AGift.getInstance().getConfig().getString("database.mysql.username");
            this.password = AGift.getInstance().getConfig().getString("database.mysql.password");
            this.connectionString = "jdbc:mysql://" + host + ":" + port + "/" + dbName;
        } else {
            // 默认SQLite
            String dbFile = AGift.getInstance().getConfig().getString("database.sqlite.file");
            this.connectionString = "jdbc:sqlite:plugins/AGift/" + dbFile;
            this.username = null;
            this.password = null;
        }
        connect();
    }

    /**
     * 连接数据库方法
     * <p>
     * 此方法根据配置文件中指定的数据库类型来建立数据库连接如果配置的数据库类型为MySQL，
     * 则加载MySQL驱动并使用提供的凭据建立连接对于其他数据库类型，直接使用提供的连接字符串建立连接
     * 在成功建立连接后，调用createTables方法来创建必要的数据库表
     * <p>
     * 注意：此方法捕获SQLException和ClassNotFoundException异常，分别处理数据库连接问题和驱动类加载问题
     */
    private void connect() {
        try {
            // 检查配置文件中指定的数据库类型是否为MySQL
            if ("mysql".equalsIgnoreCase(AGift.getInstance().getConfig().getString("database.type"))) {
                // 加载MySQL驱动
                Class.forName("com.mysql.cj.jdbc.Driver");
                // 使用提供的连接字符串、用户名和密码建立数据库连接
                connection = DriverManager.getConnection(connectionString, username, password);
            } else {
                // 对于非MySQL数据库，直接使用提供的连接字符串建立数据库连接
                connection = DriverManager.getConnection(connectionString);
            }
            // 创建必要的数据库表
            createTables();
        } catch (SQLException | ClassNotFoundException e) {
            // 打印异常信息，处理数据库连接问题和驱动类加载问题
            e.printStackTrace();
        }
    }


    /**
     * 创建数据库表
     * 此方法用于根据配置信息创建礼物（gifts）和邮箱（mailboxes）两个表
     * 它首先确定数据库类型（SQLite或MySQL），然后根据数据库类型构建相应的SQL语句来创建表
     */
    private void createTables() {
        try {
            // 获取数据库类型配置，默认为sqlite
            String dbType = AGift.getInstance().getConfig().getString("database.type", "sqlite");
            // 判断是否使用MySQL数据库
            boolean isMySQL = "mysql".equalsIgnoreCase(dbType);

            // 礼物表
            // 创建礼物表的SQL语句，包含自增主键id、唯一不为空的礼物名称name和不为空的礼物内容items
            String giftsTableSQL = "CREATE TABLE IF NOT EXISTS gifts (" +
                    "id INTEGER PRIMARY KEY " + (isMySQL ? "AUTO_INCREMENT" : "AUTOINCREMENT") + "," +
                    "name TEXT UNIQUE NOT NULL," +
                    "items TEXT NOT NULL" +
                    ")";

            // 邮箱表
            // 创建邮箱表的SQL语句，包含自增主键id、玩家UUID、礼物ID和接收时间
            // 如果是MySQL数据库，使用CURRENT_TIMESTAMP作为默认时间戳
            String mailboxesTableSQL = "CREATE TABLE IF NOT EXISTS mailboxes (" +
                    "id INTEGER PRIMARY KEY " + (isMySQL ? "AUTO_INCREMENT" : "AUTOINCREMENT") + "," +
                    "player_uuid TEXT NOT NULL," +
                    "gift_id INTEGER NOT NULL," +
                    "received_at TIMESTAMP DEFAULT " + (isMySQL ? "CURRENT_TIMESTAMP" : "CURRENT_TIMESTAMP") + "," +
                    "FOREIGN KEY(gift_id) REFERENCES gifts(id)" +
                    ")";

            // 执行创建礼物表和邮箱表的SQL语句
            connection.createStatement().execute(giftsTableSQL);
            connection.createStatement().execute(mailboxesTableSQL);
        } catch (SQLException e) {
            // 打印SQL异常信息
            e.printStackTrace();
        }
    }

    public Connection getConnection() {
        try {
            if (connection == null || connection.isClosed()) {
                connect();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
    public void close() {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

